import {
  IsString,
  IsOptional,
  IsEnum,
  IsBoolean,
  IsArray,
  IsObject,
  IsDateString,
  IsUUID,
  IsInt,
  IsUrl,
  MinLength,
  MaxLength,
  Min,
  Max,
  ValidateNested,
  ArrayMinSize,
  ArrayMaxSize
} from 'class-validator'
import { Type, Transform, Expose } from 'class-transformer'
import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger'
import { BaseDto, PaginationDto } from './base.dto'
import { IsValidSlug, IsValidTags } from '../validators/custom.validator'

/**
 * 内容类型枚举
 */
export enum ContentType {
  ARTICLE = 'article',
  PAGE = 'page',
  NEWS = 'news',
  BLOG = 'blog',
  PRODUCT = 'product',
  EVENT = 'event',
  PORTFOLIO = 'portfolio',
  DOCUMENTATION = 'documentation'
}

/**
 * 内容状态枚举
 */
export enum ContentStatus {
  DRAFT = 'draft',
  PUBLISHED = 'published',
  ARCHIVED = 'archived',
  SCHEDULED = 'scheduled',
  REVIEWING = 'reviewing',
  REJECTED = 'rejected'
}

/**
 * 内容格式枚举
 */
export enum ContentFormat {
  MARKDOWN = 'markdown',
  HTML = 'html',
  RICH_TEXT = 'rich_text',
  PLAIN_TEXT = 'plain_text'
}

/**
 * SEO配置DTO
 */
export class SeoConfigDto {
  @ApiPropertyOptional({ description: 'SEO标题' })
  @IsOptional()
  @IsString()
  @MaxLength(60)
  title?: string

  @ApiPropertyOptional({ description: 'SEO描述' })
  @IsOptional()
  @IsString()
  @MaxLength(160)
  description?: string

  @ApiPropertyOptional({ description: 'SEO关键词' })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  @ArrayMaxSize(10)
  keywords?: string[]

  @ApiPropertyOptional({ description: '规范链接' })
  @IsOptional()
  @IsUrl()
  canonicalUrl?: string

  @ApiPropertyOptional({ description: '是否允许索引' })
  @IsOptional()
  @IsBoolean()
  noIndex?: boolean

  @ApiPropertyOptional({ description: '是否允许跟踪链接' })
  @IsOptional()
  @IsBoolean()
  noFollow?: boolean

  @ApiPropertyOptional({ description: 'Open Graph标题' })
  @IsOptional()
  @IsString()
  @MaxLength(60)
  ogTitle?: string

  @ApiPropertyOptional({ description: 'Open Graph描述' })
  @IsOptional()
  @IsString()
  @MaxLength(160)
  ogDescription?: string

  @ApiPropertyOptional({ description: 'Open Graph图片' })
  @IsOptional()
  @IsUrl()
  ogImage?: string

  @ApiPropertyOptional({ description: 'Twitter卡片类型' })
  @IsOptional()
  @IsString()
  twitterCard?: string
}

/**
 * 内容设置DTO
 */
export class ContentSettingsDto {
  @ApiPropertyOptional({ description: '是否允许评论' })
  @IsOptional()
  @IsBoolean()
  allowComments?: boolean

  @ApiPropertyOptional({ description: '是否置顶' })
  @IsOptional()
  @IsBoolean()
  isPinned?: boolean

  @ApiPropertyOptional({ description: '是否推荐' })
  @IsOptional()
  @IsBoolean()
  isFeatured?: boolean

  @ApiPropertyOptional({ description: '是否需要密码访问' })
  @IsOptional()
  @IsBoolean()
  isPasswordProtected?: boolean

  @ApiPropertyOptional({ description: '访问密码' })
  @IsOptional()
  @IsString()
  @MinLength(4)
  @MaxLength(20)
  password?: string

  @ApiPropertyOptional({ description: '阅读时间（分钟）' })
  @IsOptional()
  @IsInt()
  @Min(1)
  @Max(999)
  readingTime?: number

  @ApiPropertyOptional({ description: '内容难度等级' })
  @IsOptional()
  @IsEnum(['beginner', 'intermediate', 'advanced'])
  difficulty?: string

  @ApiPropertyOptional({ description: '内容语言' })
  @IsOptional()
  @IsString()
  @MaxLength(10)
  language?: string

  @ApiPropertyOptional({ description: '版权信息' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  copyright?: string

  @ApiPropertyOptional({ description: '许可证类型' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  license?: string
}

/**
 * 创建内容DTO
 */
export class CreateContentDto {
  @ApiProperty({ description: '内容标题' })
  @IsString()
  @MinLength(1)
  @MaxLength(200)
  title: string

  @ApiPropertyOptional({ description: '内容副标题' })
  @IsOptional()
  @IsString()
  @MaxLength(300)
  subtitle?: string

  @ApiProperty({ description: '内容正文' })
  @IsString()
  @MinLength(1)
  content: string

  @ApiPropertyOptional({ description: '内容摘要' })
  @IsOptional()
  @IsString()
  @MaxLength(500)
  excerpt?: string

  @ApiProperty({
    description: '内容类型',
    enum: ContentType,
    default: ContentType.ARTICLE
  })
  @IsEnum(ContentType)
  type: ContentType

  @ApiProperty({
    description: '内容状态',
    enum: ContentStatus,
    default: ContentStatus.DRAFT
  })
  @IsEnum(ContentStatus)
  status: ContentStatus

  @ApiProperty({
    description: '内容格式',
    enum: ContentFormat,
    default: ContentFormat.MARKDOWN
  })
  @IsEnum(ContentFormat)
  format: ContentFormat

  @ApiPropertyOptional({ description: '内容别名/URL路径' })
  @IsOptional()
  @IsString()
  @IsValidSlug()
  @MaxLength(100)
  slug?: string

  @ApiPropertyOptional({ description: '分类ID' })
  @IsOptional()
  @IsUUID()
  categoryId?: string

  @ApiPropertyOptional({ description: '标签列表' })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  @IsValidTags()
  @ArrayMaxSize(20)
  tags?: string[]

  @ApiPropertyOptional({ description: '特色图片URL' })
  @IsOptional()
  @IsUrl()
  featuredImage?: string

  @ApiPropertyOptional({ description: '特色图片描述' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  featuredImageAlt?: string

  @ApiPropertyOptional({ description: '发布时间' })
  @IsOptional()
  @IsDateString()
  publishedAt?: string

  @ApiPropertyOptional({ description: 'SEO配置' })
  @IsOptional()
  @ValidateNested()
  @Type(() => SeoConfigDto)
  seoConfig?: SeoConfigDto

  @ApiPropertyOptional({ description: '内容设置' })
  @IsOptional()
  @ValidateNested()
  @Type(() => ContentSettingsDto)
  settings?: ContentSettingsDto

  @ApiPropertyOptional({ description: '自定义字段' })
  @IsOptional()
  @IsObject()
  customFields?: Record<string, any>

  @ApiPropertyOptional({ description: '模板名称' })
  @IsOptional()
  @IsString()
  @MaxLength(50)
  template?: string

  @ApiPropertyOptional({ description: '排序权重' })
  @IsOptional()
  @IsInt()
  @Min(0)
  @Max(9999)
  sortOrder?: number
}

/**
 * 更新内容DTO
 */
export class UpdateContentDto extends PartialType(CreateContentDto) {
  @ApiPropertyOptional({ description: '更新原因' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  updateReason?: string

  @ApiPropertyOptional({ description: '是否创建新版本' })
  @IsOptional()
  @IsBoolean()
  createVersion?: boolean
}

/**
 * 查询内容DTO
 */
export class QueryContentDto extends PaginationDto {
  @ApiPropertyOptional({ description: '搜索关键词' })
  @IsOptional()
  @IsString()
  @MaxLength(100)
  search?: string = ''

  @ApiPropertyOptional({
    description: '内容类型',
    enum: ContentType
  })
  @IsOptional()
  @IsEnum(ContentType)
  type?: ContentType

  @ApiPropertyOptional({
    description: '内容状态',
    enum: ContentStatus
  })
  @IsOptional()
  @IsEnum(ContentStatus)
  status?: ContentStatus

  @ApiPropertyOptional({ description: '分类ID' })
  @IsOptional()
  @IsUUID()
  categoryId?: string

  @ApiPropertyOptional({ description: '作者ID' })
  @IsOptional()
  @IsUUID()
  authorId?: string

  @ApiPropertyOptional({ description: '标签（多个用逗号分隔）' })
  @IsOptional()
  @IsString()
  tags?: string

  @ApiPropertyOptional({ description: '是否置顶' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  isPinned?: boolean

  @ApiPropertyOptional({ description: '是否推荐' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  isFeatured?: boolean

  @ApiPropertyOptional({ description: '发布开始时间' })
  @IsOptional()
  @IsDateString()
  publishedAfter?: string

  @ApiPropertyOptional({ description: '发布结束时间' })
  @IsOptional()
  @IsDateString()
  publishedBefore?: string

  @ApiPropertyOptional({ description: '创建开始时间' })
  @IsOptional()
  @IsDateString()
  createdAfter?: string

  @ApiPropertyOptional({ description: '创建结束时间' })
  @IsOptional()
  @IsDateString()
  createdBefore?: string

  @ApiPropertyOptional({ description: '最小浏览量' })
  @IsOptional()
  @Transform(({ value }) => parseInt(value))
  @IsInt()
  @Min(0)
  minViews?: number

  @ApiPropertyOptional({ description: '最大浏览量' })
  @IsOptional()
  @Transform(({ value }) => parseInt(value))
  @IsInt()
  @Min(0)
  maxViews?: number

  @ApiPropertyOptional({ description: '是否包含草稿' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  includeDrafts?: boolean

  @ApiPropertyOptional({ description: '是否包含已归档' })
  @IsOptional()
  @Transform(({ value }) => value === 'true')
  @IsBoolean()
  includeArchived?: boolean
}

/**
 * 内容响应DTO
 */
export class ContentResponseDto extends BaseDto {
  @ApiProperty({ description: '内容标题' })
  @Expose()
  title: string

  @ApiPropertyOptional({ description: '内容副标题' })
  @Expose()
  subtitle?: string

  @ApiProperty({ description: '内容正文' })
  @Expose()
  content: string

  @ApiPropertyOptional({ description: '内容摘要' })
  @Expose()
  excerpt?: string

  @ApiProperty({ description: '内容类型', enum: ContentType })
  @Expose()
  type: ContentType

  @ApiProperty({ description: '内容状态', enum: ContentStatus })
  @Expose()
  status: ContentStatus

  @ApiProperty({ description: '内容格式', enum: ContentFormat })
  @Expose()
  format: ContentFormat

  @ApiPropertyOptional({ description: '内容别名' })
  @Expose()
  slug?: string

  @ApiPropertyOptional({ description: '分类信息' })
  @Expose()
  category?: {
    id: string
    name: string
    slug: string
  }

  @ApiPropertyOptional({ description: '作者信息' })
  @Expose()
  author?: {
    id: string
    username: string
    nickname: string
    avatar?: string
  }

  @ApiPropertyOptional({ description: '标签列表' })
  @Expose()
  tags?: string[]

  @ApiPropertyOptional({ description: '特色图片URL' })
  @Expose()
  featuredImage?: string

  @ApiPropertyOptional({ description: '特色图片描述' })
  @Expose()
  featuredImageAlt?: string

  @ApiPropertyOptional({ description: '发布时间' })
  @Expose()
  publishedAt?: Date

  @ApiProperty({ description: '浏览量' })
  @Expose()
  views: number

  @ApiProperty({ description: '点赞数' })
  @Expose()
  likesCount: number

  @ApiProperty({ description: '评论数' })
  @Expose()
  commentsCount: number

  @ApiProperty({ description: '收藏数' })
  @Expose()
  bookmarksCount: number

  @ApiPropertyOptional({ description: 'SEO配置' })
  @Expose()
  seoConfig?: SeoConfigDto

  @ApiPropertyOptional({ description: '内容设置' })
  @Expose()
  settings?: ContentSettingsDto

  @ApiPropertyOptional({ description: '自定义字段' })
  @Expose()
  customFields?: Record<string, any>

  @ApiPropertyOptional({ description: '模板名称' })
  @Expose()
  template?: string

  @ApiProperty({ description: '排序权重' })
  @Expose()
  sortOrder: number

  @ApiProperty({ description: '版本号' })
  @Expose()
  version: number

  @ApiPropertyOptional({ description: '最后编辑者' })
  @Expose()
  lastEditor?: {
    id: string
    username: string
    nickname: string
  }

  @ApiPropertyOptional({ description: '最后编辑时间' })
  @Expose()
  lastEditedAt?: Date

  @ApiPropertyOptional({ description: '预计阅读时间（分钟）' })
  @Expose()
  estimatedReadingTime?: number

  @ApiPropertyOptional({ description: '内容字数' })
  @Expose()
  wordCount?: number

  @ApiPropertyOptional({ description: '相关内容' })
  @Expose()
  relatedContent?: Array<{
    id: string
    title: string
    slug: string
    featuredImage?: string
  }>
}

/**
 * 内容统计DTO
 */
export class ContentStatsDto {
  @ApiProperty({ description: '总内容数' })
  @Expose()
  totalContent: number

  @ApiProperty({ description: '已发布内容数' })
  @Expose()
  publishedContent: number

  @ApiProperty({ description: '草稿数' })
  @Expose()
  draftContent: number

  @ApiProperty({ description: '已归档内容数' })
  @Expose()
  archivedContent: number

  @ApiProperty({ description: '待审核内容数' })
  @Expose()
  reviewingContent: number

  @ApiProperty({ description: '总浏览量' })
  @Expose()
  totalViews: number

  @ApiProperty({ description: '总点赞数' })
  @Expose()
  totalLikes: number

  @ApiProperty({ description: '总评论数' })
  @Expose()
  totalComments: number

  @ApiProperty({ description: '总收藏数' })
  @Expose()
  totalBookmarks: number

  @ApiProperty({ description: '按类型统计' })
  @Expose()
  byType: Record<ContentType, number>

  @ApiProperty({ description: '按状态统计' })
  @Expose()
  byStatus: Record<ContentStatus, number>

  @ApiProperty({ description: '最近7天新增内容数' })
  @Expose()
  recentContent: number

  @ApiProperty({ description: '最受欢迎内容' })
  @Expose()
  popularContent: Array<{
    id: string
    title: string
    views: number
    likes: number
  }>

  @ApiProperty({ description: '最新内容' })
  @Expose()
  latestContent: Array<{
    id: string
    title: string
    createdAt: Date
    status: ContentStatus
  }>
}

/**
 * 批量内容操作DTO
 */
export class BulkContentOperationDto {
  @ApiProperty({
    description: '操作类型',
    enum: ['publish', 'unpublish', 'archive', 'delete', 'update_category', 'update_tags']
  })
  @IsEnum(['publish', 'unpublish', 'archive', 'delete', 'update_category', 'update_tags'])
  operation: string

  @ApiProperty({ description: '内容ID列表' })
  @IsArray()
  @IsUUID(4, { each: true })
  @ArrayMinSize(1)
  @ArrayMaxSize(100)
  items: string[]

  @ApiPropertyOptional({ description: '操作参数' })
  @IsOptional()
  @IsObject()
  params?: {
    categoryId?: string
    tags?: string[]
    publishAt?: string
    [key: string]: any
  }

  @ApiPropertyOptional({ description: '操作原因' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  reason?: string
}

/**
 * 发布内容DTO
 */
export class PublishContentDto {
  @ApiPropertyOptional({ description: '发布时间（留空表示立即发布）' })
  @IsOptional()
  @IsDateString()
  publishAt?: string

  @ApiPropertyOptional({ description: '发布说明' })
  @IsOptional()
  @IsString()
  @MaxLength(200)
  publishNote?: string

  @ApiPropertyOptional({ description: '是否发送通知' })
  @IsOptional()
  @IsBoolean()
  sendNotification?: boolean

  @ApiPropertyOptional({ description: '通知渠道' })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  notificationChannels?: string[]
}

/**
 * 内容版本DTO
 */
export class ContentVersionDto extends BaseDto {
  @ApiProperty({ description: '内容ID' })
  @Expose()
  contentId: string

  @ApiProperty({ description: '版本号' })
  @Expose()
  version: number

  @ApiProperty({ description: '版本标题' })
  @Expose()
  title: string

  @ApiProperty({ description: '版本内容' })
  @Expose()
  content: string

  @ApiPropertyOptional({ description: '变更说明' })
  @Expose()
  changeLog?: string

  @ApiProperty({ description: '创建者信息' })
  @Expose()
  creator: {
    id: string
    username: string
    nickname: string
  }

  @ApiProperty({ description: '是否为当前版本' })
  @Expose()
  isCurrent: boolean

  @ApiProperty({ description: '内容大小（字节）' })
  @Expose()
  contentSize: number

  @ApiPropertyOptional({ description: '与上一版本的差异统计' })
  @Expose()
  diffStats?: {
    additions: number
    deletions: number
    changes: number
  }
}

/**
 * 内容搜索DTO
 */
export class ContentSearchDto {
  @ApiProperty({ description: '搜索关键词' })
  @IsString()
  @MinLength(1)
  @MaxLength(100)
  query: string

  @ApiPropertyOptional({ description: '内容类型' })
  @IsOptional()
  @IsEnum(ContentType)
  type?: ContentType

  @ApiPropertyOptional({ description: '分类ID' })
  @IsOptional()
  @IsUUID()
  category?: string

  @ApiPropertyOptional({ description: '标签' })
  @IsOptional()
  @IsArray()
  @IsString({ each: true })
  tags?: string[]

  @ApiPropertyOptional({ description: '作者ID' })
  @IsOptional()
  @IsUUID()
  author?: string

  @ApiPropertyOptional({ description: '搜索范围' })
  @IsOptional()
  @IsArray()
  @IsEnum(['title', 'content', 'excerpt', 'tags'], { each: true })
  searchIn?: string[]

  @ApiPropertyOptional({ description: '页码' })
  @IsOptional()
  @Transform(({ value }) => parseInt(value))
  @IsInt()
  @Min(1)
  page?: number = 1

  @ApiPropertyOptional({ description: '每页数量' })
  @IsOptional()
  @Transform(({ value }) => parseInt(value))
  @IsInt()
  @Min(1)
  @Max(100)
  limit?: number = 20

  @ApiPropertyOptional({ description: '排序字段' })
  @IsOptional()
  @IsEnum(['relevance', 'created_at', 'updated_at', 'published_at', 'views', 'likes'])
  sortBy?: string = 'relevance'

  @ApiPropertyOptional({ description: '排序方向' })
  @IsOptional()
  @IsEnum(['asc', 'desc'])
  sortOrder?: string = 'desc'
}
